﻿using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace IkeCode.WP7.Toolkit.Base
{
    /// <summary>
    /// Converter to Class/Interface
    /// </summary>
    /// <typeparam name="TInterface">Interface</typeparam>
    /// <typeparam name="TModel">Class</typeparam>
    internal class IcJsonInterfaceConverter<TInterface, TModel> : CustomCreationConverter<TInterface>
        where TInterface : IIcBase
        where TModel : TInterface, new()
    {
        /// <summary>
        /// Override create method
        /// </summary>
        /// <param name="objectType"></param>
        /// <returns></returns>
        public override TInterface Create(Type objectType)
        {
            return new TModel();
        }
    }

    /// <summary>
    /// Wrap for Newtonsoft serializer
    /// </summary>
    public class IcJsonSerializer
    {
        /// <summary>
        /// Get available converters
        /// </summary>
        /// <typeparam name="TModel">Type of model</typeparam>
        /// <typeparam name="TInterface">Type of Interface</typeparam>
        /// <returns>JsonConverter array</returns>
        public static JsonConverter[] GetConverters<TModel, TInterface>()
            where TInterface : IIcBase
            where TModel : TInterface, new()
        {
            List<JsonConverter> converters = new List<JsonConverter>();
            converters.Add(new IcJsonInterfaceConverter<TInterface, TModel>());

            return converters.ToArray();
        }

        /// <summary>
        /// Serialize method
        /// </summary>
        /// <param name="data">Data to be serialized</param>
        /// <returns>Json string</returns>
        public static string Serialize(object data)
        {
            return JsonConvert.SerializeObject(data,
                    Formatting.None,
                    new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
        }

        /// <summary>
        /// Deserialize method
        /// </summary>
        /// <typeparam name="TModel">Type of return</typeparam>
        /// <param name="data">Json string</param>
        /// <returns>TModel</returns>
        public static TModel Deserialize<TModel>(string data)
        {
            return JsonConvert.DeserializeObject<TModel>(data);
        }

        /// <summary>
        /// Deserialize method
        /// </summary>
        /// <typeparam name="TModel">Type of model</typeparam>
        /// <typeparam name="TInterface">Type of return</typeparam>
        /// <param name="data">Json string</param>
        /// <returns>TInterface</returns>
        public static TInterface Deserialize<TModel, TInterface>(string data)
            where TInterface : IIcBase
            where TModel : TInterface, new()
        {
            JsonConverter[] converters = GetConverters<TModel, TInterface>();
            return JsonConvert.DeserializeObject<TModel>(data, converters);
        }

        /// <summary>
        /// Deserialize method
        /// </summary>
        /// <typeparam name="TModel">Type of model</typeparam>
        /// <typeparam name="TInterface">Type of return</typeparam>
        /// <param name="data">Json string</param>
        /// <returns>List of TInterface</returns>
        public static List<TInterface> DeserializeList<TModel, TInterface>(string data)
            where TInterface : IIcBase
            where TModel : TInterface, new()
        {
            JsonConverter[] converters = GetConverters<TModel, TInterface>();
            return JsonConvert.DeserializeObject<List<TInterface>>(data, converters);
        }
    }
}
